Register-Lib PowerShell.Files

filter Replace-Contents {
	param(
        [scriptblock]$Process  = $(throw "Parameter '-Process' (position 1) is required"),
        [switch]$Whatif,
        [switch]$Verbose,
        [switch]$MakeBak
        )
        
	$file = $_ | Get-Item 
    $newFile = "$file.replaced"   
        
    if ($Verbose){
        Log "Replace-Contents: $file"
    }
  
    $changed = $false
    
    $ConvertVerbose = $Verbose -or $Whatif
    
    Get-Content $file | % { 
        $line = $_; 
        $newLine = Convert-Item $_ $Process -Verbose:$ConvertVerbose; 
        if ($line -cne $newLine) { 
            $changed= $true 
        }; 
        $newLine 
    } | Out-File $newfile -enc ASCII
    
    if ($Whatif -or -not $changed) {        
        Remove-Item $newfile
        if ($changed) {
            if ($Whatif){
                Log "Changes were not applied (-Whatif) to: $file"
                return $file;
            }                        
        } else {
            return;
        }
    } 
    else {
        if ($MakeBak){
           Move-Item $file "$file.bak"
        }
        move $newFile $file -force
        if ($Verbose) {
            Log "`tFile was modified: $file"
        }
        return $file
    }
}

Function Convert-Item {
    param ( 
        $line,
        [scriptblock]$Process,
        [switch]$Whatif,
        [Switch]$Verbose
    )
    $result = $line | % $Process
    if ($result -ceq $null) {        
        return $line
    }    
    if ($result -cne $line) {
        if ($Whatif -or $Verbose) {
            Log "`tCHANGE: $line"
            Log "`tTO:     $result"            
        }         
    }
    if ($Whatif) { return $line }
    
    return $result
    
}

filter Revert-ToBak {
    param (
        [switch]$Verbose
    )
    $file = $_ | gi
    if ($file -match "\.bak$") {
        if ($Verbose) {
            Log "reverting $file"
        }
        $orig = $file -replace "\.bak$", ""
        Move-Item $file $orig -force
    }
}


function Build-ExtensionFilter($ext){
    return "(" + [string]::Join(")|(", $ext) + ")"
}

filter Add-LineCount {
	$file = gi $_
	$lines =  $file | select-string .
	Add-Member NoteProperty LineCount $lines.Count -InputObject $_
	return $_
}

# see also http://www.ayende.com/Blog/archive/7173.aspx
function Count-Lines {
	param (
		[string[]] $Patterns,
		[switch]$Verbose,
		[switch]$DotNet,
		[switch]$Sum,
		[regex] $exclude = "^$"
	)	
	begin {
		filter getLinesInFile {
			
			$file = $_
			if ($Patterns){
				$found = $false
				$Patterns | % {
					#Write-Host "match $_ : $file"
					if ($file -like $_) {
						$found = $true;
						return
					}
				}
				if (-not $found) { return ; }				
			}		
			$lines =  $file | select-string . -exclude $exclude
			if ($Verbose) { Log "`t$file : $($lines.Count)" }
			return $lines
		}		
		
		if ($Verbose) { Log "Counting lines..." }
		if ($DotNet) {
			if (-not $Patterns) { $Patterns = @() }			
			$Patterns += @("*.config", "*.cs", "*.vb")
		}
		$rollingCount = 0;
	}
	process {

		if ($_){			
			$count = ($_ | getLinesInFile).Count 
			if (-not $sum) {
				return $count
			} else {
				$rollingCount += $count
			}

		} else {
			Log "No input - default to recurse current location"
			return (dir -Recurse | getLinesInFile).Count
		}
	}
	
	end {				
		if ($_ -and $sum) { 

			return $rollingCount
		}
	}
}


function Create-RandomFileName {
param ( [string]$Extension )
$RandomFileName = [System.IO.Path]::GetRandomFileName()
if ($Extension -ne "") { $RandomFileName = [System.IO.Path]::ChangeExtension($RandomFileName, $Extension) }
return $RandomFileName 
}

function Create-TempFile {

	param ( [string]$Extension )
	 
	$RandomFileName = Create-RandomFileName -extension $Extension
	New-Item -Path $($Env:TEMP) -Name $RandomFileName -ItemType File

}


#{{{ function BackupFolder
function BackupFolder
{
    param([string] $SourceDir = $(throw 'Enter Source Directory Name'),
        [string] $DestinationDir = $(throw 'Enter Desitnation Directory Name'),
		[switch] $Force)

    if (! (test-path $SourceDir)) {
        throw "$($SourceDir) is not a valid directory!"
    }
#    if (! (test-path $DestinationDir)) {
#        throw "$($DestinationDir) is not a valid directory!"
#    }

	if (! (test-path $DestinationDir)) {
	    if ($Force) {
			Log "Creating $DestinationDir"
			new-item -Type Directory -Path $DestinationDir | out-null
		} else {
			Log "Warning: destination folder`($($DestinationDir)`) does not exist"
		    $p = Read-Host "Create folder and continue? "
		    
		    if ( $p[0] -ieq 'y' ) {
			    new-item -Type Directory -Path $DestinationDir | out-null
			} else {
				Log "Exiting script"
				WaitKey "Press any key to exit ... "
				exit
			}
		}
	}

    # Check if destination directory is missing any files in the source
    # directory.if any file is missing, copy them over to the backup dir. 
	# Log SourceDir = $SourceDir
    get-childitem $SourceDir |
    foreach {
        if ($_.PsIsContainer) {
            $childDstDir = (join-path $DestinationDir $_.Name)
			# Log "Checkign for $childDstDir"
            if (! (test-path $childDstDir)) { [void](mkdir $childDstDir) }
			# Log "recursing"
            BackupFolder $_.FullName $childDstDir
        } else {
            $srcFile = $_.FullName
            $destFile = join-path $DestinationDir $_.Name

            if (test-path $destFile) {
                $timeDiff = ($srcFile.LastWriteTime - $destFile.LastWriteTime).TotalSeconds
                if ($timeDiff -gt 2) {
                    copy-item $srcFile $destFile -Force
                    Log "Copied file $($srcFile) to $($destFile)"
                    $script:iCopyCount++
                }
            } else {
                copy-item $srcFile $destFile -Force
                Log "Copied file $($srcFile) to $($destFile)"
                $script:iCopyCount++
            }
        }
    }

    # Check if Source dir is missing any files on the backup dir.
    # if there is/are file(s) missing, copy them over from backup dir to src dir
    get-childitem $DestinationDir |
    foreach {
        if ($_.PsIsContainer) {
            $childSrcDir = (join-path $SourceDir $_.Name)
            if (! (test-path $childSrcDir)) { [void](mkdir $childSrcDir) }
            BackupFolder $childSrcDir $_.FullName
        } else {
            $srcFile = join-path $SourceDir $_.Name
            if (! (test-path $srcFile)) {
                remove-item $_
                Log "Deleted file $($_)"
                $script:iDestDeletedCount++
            }
        }
    }
}
#}}}

filter Get-Extension {
    return [System.IO.Path]::GetExtension($_)
}